package cn.yuanqiao.archive.liyong.service.impl;

import cn.yuanqiao.archive.appManager.domain.TenantRyMjDzb;
import cn.yuanqiao.archive.appManager.service.impl.TenantMijiComparisonTableServiceImpl;
import cn.yuanqiao.archive.liyong.domain.ListQuery;
import cn.yuanqiao.archive.liyong.mapper.ListQueryMapper;
import cn.yuanqiao.archive.liyong.service.ListQueryPageService;
import cn.yuanqiao.common.constant.Constants;
import cn.yuanqiao.common.core.domain.entity.SysRole;
import cn.yuanqiao.common.domain.DataScopeStaticValue;
import cn.yuanqiao.common.utils.DateUtils;
import cn.yuanqiao.common.utils.SecurityUtils;
import cn.yuanqiao.common.core.domain.entity.SysUser;
import cn.yuanqiao.common.web.page.PageDomain;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @ProjectName: JZSDAS
 * @Package: cn.yuanqiao.archive.liyong.service.impl
 * @ClassName: ListQueryPageServiceImpl
 * @Author: lenovo
 * @Description: hbWang
 * @Date: 2023/11/29 15:39
 * @Version: 1.0
 */

@Service
public class ListQueryPageServiceImpl implements ListQueryPageService {
    private static final Logger log = LoggerFactory.getLogger(ListQueryPageServiceImpl.class);
    @Autowired
    ListQueryMapper listQueryMapper;

    @Value("${FBswitch}")
    private boolean fbSwitch;

    @Autowired
    TenantMijiComparisonTableServiceImpl mijiComparisonTableService;

    @Override
    @Async
    public CompletableFuture<List<Map<String, Object>>> queryList(String field, String sql, String query,
                                                                  ListQuery listQuery, SysUser user, String tenantCode) {
        log.info("开始查询数据列表=" + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss.SSS", new Date()));
        PageDomain pageDomain = listQuery.getPageDomain();
        Integer pageSize = pageDomain.getPageSize();
        Integer pageNum = (pageDomain.getPageNum() - 1) * pageSize;
        if (fbSwitch && (field.contains(",MJ")||field.contains("MJ,"))) {
            List<TenantRyMjDzb> getdamjbyrymj = mijiComparisonTableService.getdamjbyrymjCode(user, user.getTenantCode());
            query =  (query == null ?"":query)+" and MJ in ('" + getdamjbyrymj.stream().map(m->m.getDaMj()).collect(Collectors.joining("','")) +"') ";
        }
        List<Map<String, Object>> data = listQueryMapper.selectUnionALLTableData(field, sql, listQuery.getOrder(), query, pageSize, pageNum);
        List<Map<String, Object>> authority = authority(data, listQuery.getMenuId(), user, tenantCode);
        log.info("结束查询数据列表=" + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss.SSS", new Date()));
        if (authority == null) {
            authority = new ArrayList<>();
        }
        return CompletableFuture.completedFuture(authority);
    }

    @Override
//    @Async
    public Integer queryTotal(String sql, String query, String field,SysUser user) {
        log.info("开始查询总数=" + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss.SSS", new Date()));
        if (fbSwitch && (field.contains(",MJ")||field.contains("MJ,"))) {
            List<TenantRyMjDzb> getdamjbyrymj = mijiComparisonTableService.getdamjbyrymjCode(user, user.getTenantCode());
            query =  (query == null ?"":query)+" and MJ in ('" + getdamjbyrymj.stream().map(m->m.getDaMj()).collect(Collectors.joining("','")) +"') ";
        }
        List<Map<String, Object>> data = listQueryMapper.selectUnionALLTableDataCount(field, sql, null, query);
        String sum = data.get(0).get("SUN") == null ? "0" : data.get(0).get("SUN").toString();
        log.info("结束查询总数=" + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss.SSS", new Date()));
        return Integer.parseInt(sum);
    }

    @Override
    @Async
    public CompletableFuture<Integer> queryListCount(String field, String sql, String query,
                                                     ListQuery listQuery, SysUser user, String tenantCode) {
        log.info("开始查询数据分页数量=" + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss.SSS", new Date()));
        PageDomain pageDomain = listQuery.getPageDomain();
        Integer pageSize = pageDomain.getPageSize();
        Integer pageNum = (pageDomain.getPageNum() - 1) * pageSize;
        if (fbSwitch && (field.contains(",MJ") || field.contains("MJ,"))) {
            List<TenantRyMjDzb> getdamjbyrymj = mijiComparisonTableService.getdamjbyrymjCode(user, user.getTenantCode());
            query = (query == null ? "" : query) + " and MJ in ('" + getdamjbyrymj.stream().map(m -> m.getDaMj()).collect(Collectors.joining("','")) + "') ";
        }
        if (pageNum < 7) {
            pageSize = pageSize * pageNum;
        } else {
            pageSize = (pageSize + 4) * pageNum;
        }
        List<Map<String, Object>> data = listQueryMapper.selectUnionALLTableData(field, sql, listQuery.getOrder(), query, pageSize, null);
        log.info("结束查询数据分页数量=" + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss.SSS", new Date()));

        return CompletableFuture.completedFuture(Integer.valueOf(data.size()));
    }

    /**
     * 借阅权限
     *
     * @param dataList
     * @param menuId
     * @return
     */
    @Override
    public List<Map<String, Object>> authority(List<Map<String, Object>> dataList, String menuId, SysUser user, String tenantCode) {
        if (ObjectUtils.isEmpty(dataList)) {
            return null;
        }
        boolean allMatch = false;

        List<SysRole> roles = user.getRoles();
        if (roles != null && roles.size() > 0) {
            allMatch = roles.stream().anyMatch(a -> a.getRoleKey().trim().equals("dagly"));
        }
        for (Map<String, Object> data : dataList) {
            //is_borrowing_car   0 不需要借阅 1 需要借阅
            int isBorrowingCar = 1;
            if (allMatch) {
                data.put("is_borrowing_car", "0");
                continue;
            }
            if (data.containsKey("IS_OPENS")) {
                //IS_OPENS  0 不开放  1 开放
                String isOpens = data.get("IS_OPENS") == null ? "" : data.get("IS_OPENS").toString();
                if ("1".equals(isOpens)) {
                    data.put("is_borrowing_car", "0");
                    continue;
                }
            }
            String tableName = data.get("SUB_TABLE_NAME") == null ? "" : data.get("SUB_TABLE_NAME").toString();
            String tablenametype = tableName.substring(tableName.length() - 3, tableName.length() - 2);
            if (isBorrowingCar == 1) {
                if (data.containsKey("CREATE_ID")) {
                    StringBuilder sql = new StringBuilder();
                    //归档处室
                    String gdcsId = null;
                    if (data.containsKey("GDCS_ID")) {
                        gdcsId = data.get("GDCS_ID") == null ? "" : data.get("GDCS_ID").toString();
                    }
                    if ("F".equalsIgnoreCase(tablenametype)) {//档案层
                        sql.append(" FILE_TABLE_NAME = '");
                    } else if ("V".equalsIgnoreCase(tablenametype)) {//案卷层
                        sql.append(" FOLDER_TABLE_NAME = '");
                    } else if ("X".equalsIgnoreCase(tablenametype)) {//项目层
                        sql.append(" ITEM_TABLE_NAME = '");
                    }
                    sql.append(tableName).append("' and is_del=0 ");
                    //创建人id
                    String createId = data.get("CREATE_ID") == null ? "" : data.get("CREATE_ID").toString();
                    String categoryId = listQueryMapper.selectAppData(tenantCode + Constants.BIG_TABLE_NAME, " ID ", sql.toString());
                    if (roleTree(menuId, createId, categoryId, gdcsId, user, tenantCode)) {
                        isBorrowingCar = 0;
                    }
                }
            }
            //       }
            data.put("is_borrowing_car", isBorrowingCar);
        }
        return dataList;
    }


    /**
     * 角色判断
     *
     * @param menuId     菜单id
     * @param createId   门类id
     * @param categoryId 门类和元数据方案关联id
     *                   gdcsId 归档处室
     * @return
     */
    public boolean roleTree(String menuId, String createId, String categoryId, String gdcsId, SysUser user, String tenantCode) {
        boolean b = false;
        Long dept = user.getDeptId();
        List<SysRole> roles = user.getRoles();
        if (roles != null && roles.size() > 0) {
            for (SysRole role : roles) {
                StringBuilder sqlStringTr = new StringBuilder();
                //查询角色关联档案门类
                sqlStringTr.append(" id in ( select tree_id from ").append(tenantCode + "_TREESROLE")
                        .append(" where  ROLE_ID = '").append(role.getRoleId()).append("' AND MENU_ID = '").append(menuId).append("' ) and category_id = '")
                        .append(categoryId).append("' ");
                String countCgId = listQueryMapper.selectAppData(tenantCode + Constants.ABLE_TREES, " COUNT(*) ", sqlStringTr.toString());
                if (!"0".equals(countCgId)) {
                    StringBuilder sqlString = new StringBuilder();
                    String dataScope = role.getDataScope();
                    String userIdNum = "0";
                    if (DataScopeStaticValue.DATA_SCOPE_ALL.equals(dataScope)) {
                        userIdNum = "1";
                    } else if (DataScopeStaticValue.DATA_SCOPE_CUSTOM.equals(dataScope)) {
                        if (StringUtils.isBlank(gdcsId)) {
                            continue;
                        }
                        sqlString.append(" ROLE_ID='").append(role.getRoleId()).append("' and dept_id=  '")
                                .append(gdcsId).append("' ");
                        userIdNum = listQueryMapper.selectAppData(" sys_role_dept ", " COUNT(*) ", sqlString.toString());
                    } else if (DataScopeStaticValue.DATA_SCOPE_DEPT.equals(dataScope)) {
                        if (StringUtils.isBlank(gdcsId)) {
                            continue;
                        }
//                        sqlString.append(" su.dept_id in ( select dept_id from sys_dept where dept_id = '")
//                                .append(dept).append("' ) and su.user_id=  '").append(createId).append("' ");
                        //userIdNum = listQueryMapper.selectAppData(" sys_user su ", " COUNT(*) ", sqlString.toString());
                        if (dept.equals(gdcsId)) {
                            userIdNum = "1";
                        }
                    } else if (DataScopeStaticValue.DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) {
//                        sqlString.append(" su.dept_id in ( select dept_id from sys_dept where dept_id = '")
//                                .append(dept).append("' or find_in_set( '").append(dept).append("' , ancestors )) and su.user_id=  '")
//                                .append(createId).append("' ");
                        if (StringUtils.isBlank(gdcsId)) {
                            continue;
                        }
                        String table = " ( select dept_id from sys_dept where dept_id = '" + dept + "' or find_in_set( '" + dept + "' , ancestors )) ";
                        sqlString.append(" dept_id = '").append(gdcsId).append("' ");
                        userIdNum = listQueryMapper.selectAppData(table, " COUNT(*) ", sqlString.toString());
                    } else if (DataScopeStaticValue.DATA_SCOPE_SELF.equals(dataScope)) {
                        if (String.valueOf(user.getUserId()).equals(createId)) {
                            userIdNum = "1";
                        }
                    } else if (DataScopeStaticValue.DATA_SCOPE_DEPT_CUSTOM.equals(dataScope)) {
                        if (StringUtils.isBlank(gdcsId)) {
                            continue;
                        }
                        sqlString.append(" ROLE_ID='").append(role.getRoleId()).append("' and dept_id=  '")
                                .append(gdcsId).append("' ");
                        userIdNum = listQueryMapper.selectAppData(" sys_role_dept ", " COUNT(*) ", sqlString.toString());
                    }
                    if (!"0".equals(userIdNum)) {
                        b = true;
                    }
                }
            }
        }
        return b;
    }

}
